#include <cassert>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include "json11.hpp"
#include <list>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <type_traits>

using namespace json11;
using namespace std;
const string simple_test =
R"(
{
  "k1":"v1",
  "k2":42, 
  "k3":1.05, 
  "k4" : true, 
  "v1":
    [
      {
        "t1":5,
        "tv":[2,3,4]
      },
      {
        "t2":false
      }
    ]
}
)";
string err;
int main()
{
  //Parse Test
  auto json = Json::parse(simple_test, err);
  printf("[Json11 Test Start]\n");
  printf("Input str :\n%s\n", simple_test.c_str());
  if (json.is_null())
  {
    printf("[Json Parse Error]%s\n", err.c_str());
    return -1;
  }
  else
    printf("[Json Parse Success]\n");

  //Read Test
  if (json["k1"].is_string())
    printf("[Read]k1=%s\n", json["k1"].string_value().c_str());
  else
    printf("[Read Err] k1\n");
  if (json["k2"].is_number())
    printf("[Read]k2=%ld\n", (long)json["k2"].number_value());
  else
    printf("[Read Err] k2\n");
  if (json["k3"].is_number())
    printf("[Read]k2=%.2lf\n", json["k3"].number_value());
  else
    printf("[Read Err] k2\n");

  //Dump Test
  string str = json.dump();
  printf("[Dump All]:\n%s\n", str.c_str());

  //Append Test
  Json js1 = Json::parse(R"({"test1":"1"})",err);
  json["v1"].append(js1);
  str = json.dump();
  printf("[Append test1]:\n%s\n", str.c_str());

  Json js2 = Json::parse(R"({"test2":"2"})",err);
  json.append("v2",js2);
  str = json.dump();
  printf("[Append test2]:\n%s\n", str.c_str());

  json.append("k2",Json(103));
  str = json.dump();
  printf("[Append test3]:\n%s\n", str.c_str());

  //Modify Test
  json["k1"] = Json("v22");
  str = json.dump();
  printf("[Modify Test1]:\n%s\n", str.c_str());

  json["k3"] = Json(true);
  str = json.dump();
  printf("[Modify Test2]:\n%s\n", str.c_str());

  json["k4"] = json["v1"][0]["tv"];
  str = json.dump();
  printf("[Modify Test2]:\n%s\n", str.c_str());

  try
  {
      json["v1"][5] = Json("hey");
      str = json.dump();
      printf("[Modify Test4]:\n%s\n", str.c_str());
  }
  catch(exception &e)
  {
    printf("[Modify Test4]:OK (%s)\n",e.what());
  }

  try
  {
      json["v1"] = Json();
      str = json.dump();
      printf("[Modify Test5]:\n%s\n", str.c_str());
  }
  catch(exception &e)
  {
    printf("[Modify Test5]:OK (%s)\n",e.what());
  }
  return 0;
}